昨天結尾我留了一句話:
這不是「它拉錯了」,而是資料裡根本沒有那個答案。
今天要證明它。
因為這兩件事看起來很像,結論卻完全相反——如果是「它拉錯了」,那我該做的是把指令寫得更嚴格;如果是「資料裡沒有」,那我把指令寫到天荒地老都沒有用。
我一開始相信的是第一個。
發現甲功能被寫到 B 頁面的當下,我的第一個反應非常直覺:
它讀得不夠仔細。
這個解釋很舒服,因為它有解法——下次規則再寫嚴一點、要求再講白一點,應該就會好。
但這個解釋撐不過三分鐘。
因為 Day 1 我就寫過,我當初給的指令是這樣的:
以頁面為單位拆分,每一頁都要各自寫出那項功能。不准寫在其中一頁,然後說「其他頁也有」。
這句話沒有模糊空間。它不是「請注意頁面」,是「每一頁各自寫」。
我交代了。而它還是把甲功能放到了 B 頁面。
所以「它沒照做」這個解釋,我沒辦法再拿來用。那就只剩下一個方向可以查:
問題不在它讀的方式,在它讀的東西。
驗證方法其實很笨,但很有效:
我把那張原始票卡打開,自己讀,然後問自己一個問題——這張卡講的功能,是哪一頁的?
結果是我也答不出來。
不是讀不懂。那張卡寫得不算差,它把功能的行為講得清清楚楚:做了什麼、什麼條件下觸發、影響到什麼。
它只是從頭到尾沒有講,這是哪一頁。
不在標題。不在描述。不在留言。不在任何一個欄位裡。
而這張卡之所以會長成這樣,原因很具體:
這項功能做在好幾個頁面上,每個頁面的長相又不太一樣——然後,只開了一張卡。
一張卡,涵蓋多個頁面,而卡上沒有任何東西區分它們。
那一刻我就知道,這不是 AI 的閱讀問題。
因為我讀同一份資料,也得不到答案。
這裡我想把話說精確一點,因為這兩個詞常常被混用,但它們的處理方式完全不同。
資訊不足,是這個欄位存在,但寫得含糊。
例:「這個功能在報表頁。」——哪一個報表頁?寫得不清楚,但追問得到。你知道要問什麼。
缺一個維度,是這個欄位根本不存在。
例:整張卡從來沒有出現過「頁面」這個概念。
差別在哪?
資訊不足的時候,你知道自己缺什麼。缺維度的時候,你連「有東西缺了」都看不出來——因為那份資料讀起來是完整的,它自洽、通順、每一句都成立。
我後來想到一個比喻:
一本只記了「幾點」、沒有記「哪一天」的行事曆。
每一條都是真的。九點開會、兩點回診,全部正確。
但你沒有辦法用它排出明天的行程——而且你翻的時候不會覺得哪裡怪,因為每一行看起來都很正常。
那份說明書的狀況就是這樣。
而接下來發生的事,幾乎是必然的:
我拿一份缺了「頁面」這個維度的資料,去要求一個需要「頁面」這個維度才答得出來的答案。
站在它的位置上想一遍,選項其實很少:
選項一:回答「這張卡沒有寫是哪一頁,我無法判斷」。
這需要一個前提——它得知道自己少了什麼。也就是說,它要先有「這件事需要頁面這個維度」的認知,再比對出「而我手上沒有」,最後還要願意交出一個不完整的答案。
選項二:填一個最合理的。
它選了這個。
而我必須誠實:如果那份資料交到一個人手上,結果不會比較好。
任何人讀那張卡,都不知道那是哪一頁。差別只有一個:
人會說「這裡沒寫清楚,我去問一下」。
而這個動作看起來是「比較負責」,但拆開來看,它需要的不是比較聰明,是兩個很具體的條件:
這兩件事,那個當下的 AI 一個都沒有。它沒有同事、沒有 Slack、沒有「等一下再說」這個選項。它被要求現在就產出一份完整的文件,而它手上那份資料答不出來。
於是它做了一件在那個處境下最自然的事:把空格填滿。
門檻那件事也一樣。原票卡寫的是「當數量 < 2」,統整之後變成「< 6」。
我一開始把它當成幻覺——它編了一個數字。
不是。
6 是真的。 那一區確實有卡片上寫著 6,只是那個 6 屬於另外一條規則。
同一個功能區,前後開了好幾張卡,各自寫了各自的門檻。它們散在不同的卡、不同的時間點,而卡片上沒有任何東西告訴你:哪一個是現在生效的那一個。
所以它做的不是「編造」,是在幾個互相衝突的來源之間做了一次選擇——而那份資料從來沒有告訴它該怎麼選。
這兩個例子擺在一起,病灶其實是同一個:
| 它缺的維度 | |
|---|---|
| 甲功能被放到 B 頁面 | 空間——這是哪一頁 |
< 2 變成 < 6 |
時間——哪一個版本是現在 |
一個缺空間,一個缺時間。
而缺時間那一個,會把我整個作法推翻——那是明天的事。
如果上面的推論成立,它應該要能解釋反面:同一個 AI、同一批卡片,為什麼資安相關的判斷一處都沒錯?
Day 8 我寫過那批的結果:某個服務的路由群組完全沒有身分驗證——屬實;連「為什麼不馬上修」的理由都對——因為呼叫端根本沒有帶憑證的能力。
那條判斷需要跨兩個系統、讀進實作細節。聽起來比「這是哪一頁」難得多。
但它對了。
原因只有一個:
答案就寫在檔案裡。
打開路由設定,看有沒有掛驗證;打開呼叫端,看那個參數有沒有被用到。它不需要推論,它只需要讀。
那個維度沒有缺。
於是 Day 8 那張表,今天可以再往下挖一層:
| 需要的維度在手上的資料裡嗎? | 結果 | |
|---|---|---|
| 資安判斷 | 在(程式碼本身就是答案) | 全部正確 |
| PR 編號 | 不在(要跨到另一個系統查) | 開始猜 |
| 頁面歸屬 | 不在(卡片沒有這個欄位) | 放錯位置 |
| 門檻數字 | 不在(沒有東西標示哪個是現行) | 選錯來源 |
這四行看起來是四種不同的錯,其實是同一行:
答案在不在它手上的那份資料裡。
而這件事最重要的地方在於——這條線是可以事先畫出來的。
我不需要等它出錯才知道它會錯在哪。我只要問一個問題:這個問題需要的維度,在我餵給它的資料裡嗎? 不在,它就會猜;而它猜的時候,產出的東西讀起來會跟正確答案一模一樣。
後來整個知識庫的架構,基本上就是從這張表長出來的。
先說我的答案:我不怪它——但這不是一句寬容。
因為在這個案子裡,它根本沒有被給到一個能答對的機會。而「有沒有給到機會」這件事,是可以事先判斷的。
我把自己的立場拆成三句話。
這句話聽起來像廢話,但它有一個很具體的反面——
你不能假設使用者知情。
那張卡之所以可以不寫頁面,靠的是一個默認的前提:讀它的人知道自己在看哪一頁。開卡的人知道、做過的人知道、當時在場的人都知道,所以那一欄不寫也沒關係。
那不是資料完整,那是資料剛好遇到了對的讀者。
而一旦讀者換人——換成 AI、換成新人、換成三個月後已經忘記的我自己——那個前提就不成立了。資料沒有變,但它突然答不出問題了。
所以「給最新的真實資料」不是對善意的期待,是義務。而且是不管誰來讀都成立的義務。
這是我最想講的一句。
那 6 個問題,確實是新人幫我抓出來的。從結果看,好像「有人會回報」這件事發揮了作用。
但那不是防線生效,那是防線不存在的證據。
因為它成立的條件太苛刻了:要有人真的照著跑、要有人肯回報、要有人回報之後我還願意去查。中間任何一環斷掉,錯誤就直接活下來。
更麻煩的是 Day 9 那個結論——最需要這份文件的人,剛好是最沒有能力驗證它的人。 新人不知道甲功能原本在 A 頁面,所以回報的是「測試失敗」,不是「文件寫錯了」。能幫我抓到,靠的是撞牆,不是判斷。
把驗證成本轉嫁給讀者,然後說「有問題會有人講」——那不是流程,那是運氣。
這條我要講清楚,因為它很容易被誤讀成「AI 不可信」。
在我這個案子裡,票卡本身就是亂的。同一處改過好幾次、同一個功能散在好幾張卡、該有的欄位沒有。
所以我的不信任,對象其實不是 AI:
在那批資料的狀態下,不管是誰來整理,我都不會直接相信結果。
換一個資深工程師來做,我一樣要查。換我自己來做——Day 8 我已經寫過了,我連自己的記憶都不敢當對照組。
我不信任的不是那個讀者,是那份資料的產物。
上面整篇我都在講「資料缺了維度」。但我必須誠實:那不是唯一的可能。
還有一個解釋我沒有辦法排除——上下文太長。
一次餵進去的東西超過它能一次握住的量,中間就會被壓縮、被摘要、被丟掉一部分。而被丟掉的那部分不會跟你說一聲。接下來它繼續往下寫,寫出來的東西一樣通順、一樣有自信,只是有些東西已經不在它手上了。
這個失敗長得跟「缺維度」一模一樣。 從外面看,你只會看到一個放錯位置的答案,你分不出來它到底是「資料裡沒有」,還是「資料裡有但它已經忘了」。
我也沒有辦法從結果反推是哪一種。我能確定的只有:那張卡確實沒有頁面這一欄——這部分我自己讀過,是硬的。但那一整批卡加起來的份量會不會也踩到了第二條線,我不知道。
而這兩個原因,剛好指向同一個方向:
不要一次丟一大包資料進去,要它產出需要精確對應的東西。
一個是因為資料裡沒有答案,一個是因為答案進去了但沒被握住。兩種都不是靠「把指令寫得更嚴格」能解決的。
這件事後來直接影響了我怎麼切資料——那是後面的篇幅。
上面三條合起來,會長出一個很具體的判準:
如果資料是乾淨的、是正確的,而它還是出錯——那我就會怪了。
這句話對我來說很重要,因為它把「怪不怪」從一個態度問題,變成一個可以檢查的問題:
第四種情況我沒有在這個專案裡遇到——但我不會假設它不存在。這條判準留著,是為了讓「不怪它」不要變成一張免死金牌。
我不怪它,是因為這一次資料不成立。不是因為它是 AI。
所以真正有用的問題,從來不是「該怪誰」,而是:
誰,該負責讓那個維度存在?
而這個問題一問出來,矛頭就指向一個比 AI 更早的地方——那張卡被開出來的時候,就已經少了一欄。
一項功能做在五個頁面上,只開一張卡。這在當下是最省事的做法,而且在當下也真的沒出事。
問題是那份資料後來被拿去做一件它從來沒有被設計要做的事:
餵給一個沒有背景知識的讀者,產出給另一群沒有背景知識的讀者看的文件。
而「沒有背景知識的讀者」——那不只是 AI,那也是新人。
這就回到 Day 9 那句話了:
抓到錯誤的前提,是你已經知道對的樣子。
AI 不知道。新人不知道。而那張卡,正好是寫給知道的人看的。
所以真正的錯不在讀的那一端。在於——我們一直用「寫給知道的人看」的資料,去服務不知道的人。
今天講的是資料缺了維度。
但你如果回頭看那兩個例子,會發現一件更麻煩的事:
它們缺的不是同一種東西。一個缺空間,一個缺時間。
而缺時間那一個,不是某張卡沒寫清楚的問題——是票卡這種東西,本質上就不該拿來回答「現在長什麼樣子」。
票卡記錄的是意圖,而且是會被後面的意圖覆蓋的意圖。同一個地方改過三次,前兩次的敘述現在都是錯的——但它們長得跟第三次一模一樣。
明天那篇要講的是:
我不是用錯了 AI。我是一開始就選錯了 source of truth。